package org.gtiles.components.login.authentication;

import java.util.HashSet;
import java.util.Set;

import org.gtiles.components.login.authentication.impl.AuthenticateDetailsImpl;
import org.gtiles.components.login.ext.CustomAuthenticateAction;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
 * 
 * 登录授权认证逻辑对象，对请求的资源进行认证过滤。如果认证失败则返回错误页面。该对象用于Spring Security配置中。
 * 对象中包含2个主要的接口对象IAuthenticateAction和IAuthenticateDetails
 * ，其中IAuthenticateAction为真正用于登录认证的逻辑实现，
 * IAuthenticateDetails用于登录成功后封装用户可访问资源、角色等信息的逻辑实现。
 * 
 * @author GuoR
 * @createDate 2016年5月17日
 */
public class CustomAuthenticationUserDetailsService
		implements UserDetailsService {

	private IAuthenticateAction authenticateAction;

	private IAuthenticateDetails authenticateDetails;
	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {

		IAuthenticatedUser authenticatedUser = getAuthenticateAction().doAuthenticate(username);
		// 其实这步骤并没必要，因为验证失败直接会抛出异常，根本不会返回null的时候
		// 但避免在其他情况，对IAuthenticateAction实现的时候出现这种情况，因此暂时保留
		if (authenticatedUser == null) {
			throw new UsernameNotFoundException("用户不存在: " + username);
		}
		
		// 增加授权角色
		Set<GrantedAuthority> grantedAuths = new HashSet<GrantedAuthority>();
		grantedAuths.add(new SimpleGrantedAuthority("IS_AUTHENTICATED_ANONYMOUSLY"));
		
		
		String[] userRoles = authenticatedUser.getUserRoles();
		if (userRoles != null) {
			for (String role : userRoles) {
				grantedAuths.add(new SimpleGrantedAuthority(role));
			}
		}
		// 登录用户的授权资源设置，如果authenticateDetails==null，则把当前登录授权用户对象代替授权资源
		//FIXME 暂时未考虑资源控制
//		 if (getAuthenticateDetails() != null) {
//			 AuthorizedDetails details = getAuthenticateDetails().doDetails(authenticatedUser);
//			 if(details.getUserResources()!=null)
//			 {
//				 for (IResource resource : details.getUserResources()) {
//					grantedAuths.add(new SimpleGrantedAuthority(resource.getResourceUri()));
//				}
//			 }
//			 if(details.getUserRoles()!=null) {
//				 for(String role:details.getUserRoles()) {
//					 grantedAuths.add(new SimpleGrantedAuthority(role));
//				 }
//			 }
//		 }
		CustomUserDatails userDetails =  new CustomUserDatails(authenticatedUser.getLoginID(), authenticatedUser.getPassword(), grantedAuths);
		userDetails.setExtendAccountInfo(authenticatedUser);
		return userDetails;
	}

	public IAuthenticateAction getAuthenticateAction() {
		if (authenticateAction == null) {
//			String authenticateActionString = (String) ConfigHolder
//					.getConfigValue(ComponentPlugin.PLUGIN_CODE,
//							"plugins_login_authenticateAction");
//			Assert.notNull(authenticateActionString,
//					"authenticateAction cannot be null");
//			if (!StringUtils.isEmpty(authenticateActionString)) {
//				try {
//					authenticateAction = (IAuthenticateAction) Class.forName(
//							authenticateActionString).newInstance();
//				} catch (Exception e) {
//					throw new RuntimeException(
//							"验证账号接口实例化失败，请检查相关参数配置及接口实现是否正确。", e);
//				}
//			}
			authenticateAction = new CustomAuthenticateAction();
		}
		return authenticateAction;
	}

	public void setAuthenticateAction(IAuthenticateAction authenticateAction) {
		this.authenticateAction = authenticateAction;
	}

	public IAuthenticateDetails getAuthenticateDetails() {
//		String authenticateDetailsString = (String) ConfigHolder
//				.getConfigValue(ComponentPlugin.PLUGIN_CODE,
//						"plugins_login_authenticateDetails");
//		Assert.notNull(authenticateDetailsString, "authenticateDetails is null");
//		if (authenticateDetails == null
//				&& !StringUtils.isEmpty(authenticateDetailsString)) {
//			try {
//				authenticateDetails = (IAuthenticateDetails) Class.forName(
//						authenticateDetailsString).newInstance();
//			} catch (Exception e) {
//				throw new RuntimeException("验证资源授权类实例化失败，请检查相关参数配置及接口实现是否正确。",
//						e);
//			}
//		}
		if(authenticateDetails==null) {
			authenticateDetails = new AuthenticateDetailsImpl();
		}
		return authenticateDetails;
	}

	public void setAuthenticateDetails(IAuthenticateDetails authenticateDetails) {
		this.authenticateDetails = authenticateDetails;
	}

}
